<template>
  <a-modal
    title="高级查询构造器"
    :width="width"
    :visible="visible"
    @cancel="handleCancel"
    :mask="false"
    :maskClosable="false"
    :confirmLoading="confirmLoading"
    class="j-super-query-modal"
  >
    <template slot="footer">
      <a-button :loading="loading" @click="handleReset">重置</a-button>
      <a-button :loading="loading" @click="handleSave">保存查询条件</a-button>
    </template>
    <a-row>
      <a-col :sm="24" :md="24-5">
        <a-form-model layout="inline" ref="form" :model="model" >
          <a-row type="flex" style="margin-bottom:10px" :gutter="16">
            <a-col :md="24" :sm="24">
              <a-descriptions bordered>
                <a-descriptions-item label="过滤条件" :labelStyle="{width: '50px'}" :contentStyle="{width:'200px'}" >
                  <a-select v-model="model.filter"   placeholder="请选择过滤条件" @change="filterChange" >
                    <a-select-option v-for="(item,index) in allFilterList" :value="item.code" >{{item.name}} </a-select-option>
                  </a-select>
                </a-descriptions-item>
              </a-descriptions>
            </a-col>
          </a-row>
          <a-row type="flex" style="margin-bottom:10px" :gutter="16" v-for="(item, index) in queryParamsModel"
                 :key="index">
            <a-col :md="24" :xs="24" v-if="index > 0">
              <a-form-item label="关联关系" :labelCol="{md: 6,xs:24}" :wrapperCol="{md: 18,xs:24}" style="width: 100%;">
                <a-radio-group v-model="item.matchType" :getPopupContainer="node=>node.parentNode"
                               style="width: 100%;">
                  <a-radio value="AND">并且</a-radio>
                  <a-radio value="OR">或者</a-radio>
                </a-radio-group>
              </a-form-item>
            </a-col>
            <a-col :span="2">
              <a-button v-if="!item.leftBracket"  @click="leftBracketClick(item,true)">(</a-button>
              <a-button type="primary" v-else   @click="leftBracketClick(item,false)">(</a-button>
            </a-col>
            <a-col :span="6" style="margin-bottom: 12px;">
              <a-select
                showSearch
                v-model="item.firstField"
                :options="firstFieldList"
                :dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
                placeholder="选择查询字段"
                allowClear
                :getPopupContainer="node=>node.parentNode"
                @change="handleSelected(item)"
              >
              </a-select>
            </a-col>
            <a-col :span="6" style="margin-bottom: 12px;">
              <a-select
                showSearch
                v-model="item.secondField"
                :dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
                placeholder="选择查询字段"
                allowClear
                :getPopupContainer="node=>node.parentNode"
                @change="secondSelected(item,null)"
              >
                <a-select-option v-for="(item,index) in item.secondFieldList" :value="item.fieldName" :key="index">
                  {{item.descr}}
                </a-select-option>
              </a-select>
            </a-col>
            <a-col :span="4" style="margin-bottom: 12px;">
              <a-select placeholder="匹配规则" :value="item.rule" :getPopupContainer="node=>node.parentNode"
                        @change="handleRuleChange(item,$event)" :options="matchTypeList" >
              </a-select>
            </a-col>
            <a-col :span="4" style="margin-bottom: 12px;">
              <j-date v-if=" item.type=='DATE'" v-model="item.val" placeholder="请选择日期" style="width: 100%"></j-date>
              <j-date
                v-else-if="((item.type?item.type:'VARCHAR2').indexOf('TIMESTAMP(6)') > -1) || (item.type=='DATE')"
                v-model="item.val" placeholder="请选择时间" :show-time="true" date-format="YYYY-MM-DD"
                style="width: 100%"></j-date>
              <a-input-number v-else-if="item.type == 'NUMBER' " :precision="item.dataScale" style="width: 100%"
                              placeholder="请输入数值" v-model="item.val"/>
              <a-select v-else-if="item.dictType" placeholder="请选择" v-model="item.val"
                        :options="item.thirdFieldList"></a-select>
              <a-input v-else v-model="item.val" placeholder="请输入值"/>
            </a-col>
            <a-col :span="2">
              <a-button v-if="!item.rightBracket"  @click="rightBracketClick(item,true)">)</a-button>
              <a-button type="primary" v-else   @click="rightBracketClick(item,false)">)</a-button>
            </a-col>
            <a-col :md="4" :xs="0" style="margin-bottom: 12px;">
              <a-button @click="handleAdd" icon="plus"></a-button>&nbsp;
              <a-button v-if="queryParamsModel.length >1 " @click="handleDel( index )" icon="minus"></a-button>
            </a-col>
          </a-row>
        </a-form-model>
      </a-col>
      <a-col :sm="24" :md="5">
        <!-- 查询记录 -->
      </a-col>
    </a-row>
  </a-modal>
</template>

<script>
  import moment from 'moment'
  import {mixinDevice} from '@/utils/mixin'
  import JDate from '@/components/jeecg/JDate.vue'
  import {getAction} from "@/api/manage";

  export default {
    name: 'SuperQueryModal',
    mixins: [mixinDevice],
    components: {JDate},
    props:{
      filter:{
        type: String,
        default:''
      }
    },
    data() {
      return {
        moment,
        loading: false,
        width: '60%',
        fieldList: {},
        firstFieldList: [],
        allFirstFieldList: [
          {value: "COMPONENT", label: "组件"},
          {value: "INSPECTION", label: "检测"},
          {value: "DOR", label: "延迟修复"},
          {value: "PRODUCT_STREAM", label: "产品流"},
          {value: "REPAIR", label: "修复"},
          {value: "COMPONENT_RULE", label: "法规"},
        ],
        allFilterList:[],
        secondFieldList: [],
        confirmLoading: false,
        model: {},
        visible: false,
        queryParamsModel: [],
        // 查询类型，过滤条件匹配（and、or）
        matchType: 'AND',
        matchTypeList: [
          {value:"=",label:"等于"},
          {value:"!=",label:"不等于"},
          {value:">",label:"大于"},
          {value:">=",label:"大于等于"},
          {value:"<",label:"小于"},
          {value:"<=",label:"小于等于"}
        ],
        url: {
          allFilter: "/queryFilter/getAllFiter",
          filterList: "/queryFilter/getSubType",
          loadThirdDict: "/queryFilter/loadThirdDict",
          filterPolicyList: "/queryFilter/getFilterPolicyList"
        }
      }
    },
    created() {
      if(this.filter){
         const filterArr = this.filter.split(",");
         this.firstFieldList = [];
         this.allFirstFieldList.forEach(item => {
             filterArr.forEach(filter =>{
                if(item.value == filter){
                  this.firstFieldList.push(item)
                }
             });
         });
      }else {
        this.firstFieldList = Object.assign([],this.allFirstFieldList);
      }
      this.getFilterList();
      this.getAllFilter();
    },
    methods: {
      leftBracketClick(item,checked){
        if(checked){
          this.$set(item,'leftBracket',"(")
        }else {
          this.$set(item,'leftBracket',"")
        }
      },
      rightBracketClick(item,checked) {
        if(checked){
          this.$set(item,'rightBracket',")")
        }else {
          this.$set(item,'rightBracket',"")
        }
      },
      filterChange(value){
        const filter = this.allFilterList.filter(item => item.code == value);
        this.queryParamsModel = []
        this.getFilterPolicyList(filter[0].filterPolicyList);
      },
      getAllFilter() {
        getAction(this.url.allFilter,{}).then(res => {
           if(res.success){
              this.allFilterList = res.result;
           }
        });
      },
      getFilterList() {
        getAction(this.url.filterList).then((res) => {
          if (res.success) {
            this.fieldList = res.result;
          }
        });
      },
      show(jsonFilter) {
        this.$nextTick(() => {
          this.model = Object.assign({}, {});
        });
        if(jsonFilter){
          this.queryParamsModel = []
          let filterJson = JSON.parse(jsonFilter);
          this.getFilterPolicyList(filterJson)
        }else {
          this.resetLine()
        }
        this.visible = true
      },
      getFilterPolicyList(filterItemList) {
          filterItemList.forEach((record,index) => {
            let condition = {
              firstField: record.mainCondition,
              secondField: record.subCondition,
              rule: record.conditionType,
              val: record.searchVal,
              leftBracket: record.leftBracket?record.leftBracket:'',
              rightBracket: record.rightBracket?record.rightBracket:'',
            };
            const filterArr = this.fieldList[record.mainCondition];
            condition.secondFieldList = filterArr;
            if (index > 0) {
              condition.matchType = record.condition;
            }
            this.queryParamsModel.push(condition);
            this.secondSelected(condition,condition.val);
        });
      },
      handleCancel() {
        this.close()
      },
      close() {
        this.$emit('close')
        this.visible = false
      },
      handleAdd() {
        this.addNewLine()
      },
      addNewLine() {
        this.queryParamsModel.push({rule: '=',leftBracket:'',rightBracket:''})
      },
      resetLine() {
        this.queryParamsModel = []
        this.addNewLine()
      },
      handleDel(index) {
        this.queryParamsModel.splice(index, 1)
      },
      handleRuleChange(item, newValue) {
        this.$set(item, 'rule', newValue);
      },
      //二级选择
      async secondSelected(item,val) {
        const secondFieldList = item.secondFieldList;
        const selectRecord = secondFieldList.filter(record => item.secondField == record.fieldName);
        this.$set(item, 'type', selectRecord[0].fieldType);
        this.$set(item, 'dataScale', selectRecord[0].dataScale);
        if (selectRecord[0].filterPolicy) {
          this.$set(item, 'dictType', selectRecord[0].filterPolicy);
          item.thirdFieldList = [];
          if (selectRecord[0].filterPolicy == 'YN') {
            item.thirdFieldList = Object.assign([], [{value: 'Y', label: '是'}, {value: 'N', label: '否'}])
          } else {
            const res = await getAction(this.url.loadThirdDict, {type: selectRecord[0].filterPolicy});
            if (res.success) {
              item.thirdFieldList = res.result;
              this.$forceUpdate();
            }
          }
        }
        if(!val) {
          this.$set(item, 'val', undefined)
        }else {
          this.$set(item, 'val', val)
        }
      },
      //一级选择
      handleSelected(item) {
        const filterArr = this.fieldList[item.firstField];
        item.secondFieldList = filterArr;
      },
      handleReset() {
        this.resetLine()
      },
      handleSave() {
        if (this.queryParamsModel.length == 0) {
          this.$message.warning('空条件不能保存')
        } else {
          let sql = "AND (";
          let sqlRemark = "(";
          let filterPolicyList = [];
          let validateFlag = true;
          this.queryParamsModel.forEach((item, index) => {
            if (!item.firstField || !item.secondField || !item.rule || !item.val) {
              this.$message.warn("配置筛选项字段所有属性必填");
              validateFlag = false;
            }
            const firstFieldRemark = this.firstFieldList.filter(firstField => firstField.value == item.firstField)[0].label;
            const secondFieldRemark =  item.secondFieldList.filter(secondField => secondField.fieldName ==  item.secondField)[0].descr;
            let valueRemark = item.val;
            if(item.dictType){
              const arr = item.thirdFieldList.filter(thirdItem => thirdItem.value == item.val);
              if(arr.length > 0 ){
                valueRemark = item.thirdFieldList.filter(thirdItem => thirdItem.value == item.val)[0].label;
              }else {
                valueRemark = '未知';
              }
            }
            if (index == 0) {
              if (((item.type ? item.type : 'VARCHAR2').indexOf('TIMESTAMP(6)') > -1) || (item.type == 'DATE')) {
                sql += item.leftBracket + "to_char(" + item.firstField + "." + item.secondField + ",'yyyy-mm-dd')" + " " + item.rule + " '" + item.val + "'" + item.rightBracket;
              } else {
                const val = (item.type.indexOf('VARCHAR2') > -1) ? ("'" + item.val + "'") : item.val;
                sql += item.leftBracket + item.firstField + "." + item.secondField + " " + item.rule + " " + val + item.rightBracket
              }
              sqlRemark += item.leftBracket + firstFieldRemark + "." + secondFieldRemark + " " + item.rule + " " + valueRemark + item.rightBracket;
              filterPolicyList.push({
                mainCondition: item.firstField,
                subCondition: item.secondField,
                conditionType: item.rule,
                searchVal: item.val,
                sequence: index,
                leftBracket: item.leftBracket,
                rightBracket: item.rightBracket,
              })
            } else {
              if (((item.type ? item.type : 'VARCHAR2').indexOf('TIMESTAMP(6)') > -1) || (item.type == 'DATE')) {
                sql += " " + item.matchType + item.leftBracket + " " + "to_char(" + item.firstField + "." + item.secondField + ",'yyyy-mm-dd')" + " " + item.rule + " '" + item.val + "'" + item.rightBracket
              } else {
                const val = (item.type.indexOf('VARCHAR2') > -1) ? ("'" + item.val + "'") : item.val;
                sql += " " + item.matchType + item.leftBracket + " " + item.firstField + "." + item.secondField + " " + item.rule + " " + val + item.rightBracket
              }
              const  combineTypeRemark = item.matchType == 'AND'?'并且':'或者'
              sqlRemark += " " + combineTypeRemark +" "+ item.leftBracket + firstFieldRemark + "." + secondFieldRemark + " " +item.rule + " " + valueRemark + item.rightBracket;
              filterPolicyList.push({
                mainCondition: item.firstField,
                subCondition: item.secondField,
                conditionType: item.rule,
                searchVal: item.val,
                condition: item.matchType,
                sequence: index,
                leftBracket: item.leftBracket,
                rightBracket: item.rightBracket,
              })
            }
          });
          sql += ")";
          sqlRemark += ")";
          if (!validateFlag) {
            return;
          }
          const jsonFields = JSON.stringify(filterPolicyList);
          let that = this;
          this.$refs.form.validate(valid => {
            if (valid) {
              that.model.sql = sql;
              that.$emit("filterSelect",sql,sqlRemark,jsonFields);
              that.visible = false;
            }
          });
        }
      },
    }
  }
</script>

<style lang="less" scoped>

  .j-super-query-box {
    display: inline-block;
  }

  .j-super-query-modal {

    .j-super-query-history-card {
      /deep/ .ant-card-body,
      /deep/ .ant-card-head-title {
        padding: 0;
      }

      /deep/ .ant-card-head {
        padding: 4px 8px;
        min-height: initial;
      }
    }

    .j-super-query-history-empty {
      /deep/ .ant-empty-image {
        height: 80px;
        line-height: 80px;
        margin-bottom: 0;
      }

      /deep/ img {
        width: 80px;
        height: 65px;
      }

      /deep/ .ant-empty-description {
        color: #afafaf;
        margin: 8px 0;
      }
    }

    .j-super-query-history-tree {

      .j-history-tree-title {
        width: calc(100% - 24px);
        position: relative;
        display: inline-block;

        &-closer {
          color: #999999;
          position: absolute;
          top: 0;
          right: 0;
          width: 24px;
          height: 24px;
          text-align: center;
          opacity: 0;
          transition: opacity 0.3s, color 0.3s;

          &:hover {
            color: #666666;
          }

          &:active {
            color: #333333;
          }
        }

        &:hover {
          .j-history-tree-title-closer {
            opacity: 1;
          }
        }

      }

      /deep/ .ant-tree-switcher {
        display: none;
      }

      /deep/ .ant-tree-node-content-wrapper {
        width: 100%;
      }
    }

  }

</style>